package partFour;
/* 本类用于实现单例设计模式实现方案2:懒汉式
 * 关于单例设计模式的俩种实现方式：
 * 1.饿汉式：不管你用不用这个类的对象，都会直接先创建一个
 * 2.懒汉式：先不给你创建这个类的对象，等你需要的时候再创建--延迟加载思想
 * 延迟加载的思想：是指不会在第一时间就把对象创建好占用内存
 *              而是什么时候用到，什么时候再去创建对象
 * 3.线程安全问题：由于我们存在唯一的对象single2，并且多条语句都操作了这个变量
 *   如果将程序放到多线程的环境下，就容易出现数据安全的问题，所以解决方案：
 *    1）将3条语句都使用同步代码块包裹，保证同步排队的效果
 *    2）由于getSingle2()只有这3条语句，所以也可以将本方法设置为静态方法*/
public class Singleton2 {
    public static void main(String[] args) {
        MySingle2 single1 = MySingle2.getSingle2();
        MySingle2 single2 = MySingle2.getSingle2();
        System.out.println(single1==single2);
        System.out.println(single1);
        System.out.println(single2);
    }
}
//0.创建自己的单例程序
class MySingle2{
    static Object o = new Object();
    //1.私有化本类的构造方法
    private MySingle2(){ }
    //2.创建的是本类对象的引用类型变量，用来保存对象的地址值，默认值是null
    private static MySingle2 single2 ;
    //3.提供公共的get方法，返回刚刚创建好的对象
    public static MySingle2 getSingle2(){
        //4.判断之前是否创建过对象，之前创建过就直接走return
        //如果之前没有创建过，走if，创建对象，并将对象返回
        //6.有共享数据+多条语句操作数据，所以尽量提前处理,避免多线程数据安全隐患
        //6.1解决方案1：加同步代码块
        //6.2解决方案2：将本方法getSingLe2()设置为同步方法
        synchronized (o) {//静态方法中使用的锁对象也得是静态的
            if (single2 == null) {//single2还是默认值，说明之前没创建过对象
                single2 = new MySingle2();//没创建过才创建，并赋值给single2
            }
            return single2;
        }
    }
}